package com.ft.oa.service.project.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ft.oa.domain.Attachment;
import com.ft.oa.domain.approval.ApplyForApproval;
import com.ft.oa.domain.check.ExecProjectExamine;
import com.ft.oa.domain.clueproject.ClueProject;
import com.ft.oa.domain.customer.Customer;
import com.ft.oa.domain.customer.CustomerOrganiza;
import com.ft.oa.domain.customer.CustomerSupplier;
import com.ft.oa.domain.dev.WeeklyReport;
import com.ft.oa.domain.dto.ApiResult;
import com.ft.oa.domain.dto.knowledgeBase.AttachmentDto;
import com.ft.oa.domain.dto.project.ExecProjectDto;
import com.ft.oa.domain.dto.project.ExecProjectPage;
import com.ft.oa.domain.dto.sys.SecurityUser;
import com.ft.oa.domain.project.*;
import com.ft.oa.domain.sys.SysDept;
import com.ft.oa.domain.sys.SysUser;
import com.ft.oa.enums.DirectoryTypeEnum;
import com.ft.oa.enums.ManagerEnum;
import com.ft.oa.enums.ProjectStages;
import com.ft.oa.enums.ProjectType;
import com.ft.oa.mapper.bidProjectMapper.BidProjectMapper;
import com.ft.oa.mapper.check.ExecProjectExamineMapper;
import com.ft.oa.mapper.clueprojectMapper.ClueProjectMapper;
import com.ft.oa.mapper.customer.CustomerMapper;
import com.ft.oa.mapper.customer.CustomerOrganizaMapper;
import com.ft.oa.mapper.customer.CustomerSupplierMapper;
import com.ft.oa.mapper.customer.ExecProjectContractMapper;
import com.ft.oa.mapper.dev.WeeklyReportMapper;
import com.ft.oa.mapper.project.*;
import com.ft.oa.mapper.sys.SysDeptMapper;
import com.ft.oa.mapper.sys.SysUserMapper;
import com.ft.oa.security.constant.SecurityConstant;
import com.ft.oa.service.approval.ApplyForApprovalService;
import com.ft.oa.service.knowledgeBase.DirectoryService;
import com.ft.oa.service.project.ExecProjectService;
import com.ft.oa.service.sys.SysUserService;
import com.ft.oa.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * 项目立项
 * @author hefeng
 * @ClassName ExecProjectServiceImpl
 * @date 2021/12/30 10:47
 */
@Service
public class ExecProjectServiceImpl extends ServiceImpl<ExecProjectMapper, ExecProject>  implements ExecProjectService {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Resource
    private ExecProjectCheckMapper execProjectCheckMapper;

    @Resource
    private ExecProjectStageMapper execProjectStageMapper;

    @Resource
    private ExecProjectContractMapper execProjectContractMapper;

    @Resource
    private ExecProjectCostMapper execProjectCostMapper;

    @Resource
    private ExecProjectCostPlanMapper execProjectCostPlanMapper;

    @Resource
    private ExecProjectContributorMapper execProjectContributorMapper;

    @Resource
    private ExecProjectNoticeMapper execProjectNoticeMapper;

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysDeptMapper sysDeptMapper;

    @Resource
    private BidProjectMapper bidProjectMapper;

    @Resource
    private ClueProjectMapper clueProjectMapper;

    @Resource
    private ApplyForApprovalService applyForApprovalService;

    @Resource
    private CustomerMapper customerMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private CustomerSupplierMapper customerSupplierMapper;

    @Resource
    private CustomerOrganizaMapper customerOrganizaMapper;

    @Resource
    private DirectoryService directoryService;
    @Resource
    private WeeklyReportMapper weeklyReportMapper;

    @Resource
    private ExecProjectExamineMapper execProjectExamineMapper;

    @Resource
    private ProjectWarrantyMapper projectWarrantyMapper;


    /**
     *
     */
    @Override
    @Transactional
    public ApiResult allExecproject(){
        QueryWrapper<ExecProject> queryWrapper = new QueryWrapper<>();
        SecurityUser currentUser = SecurityUtils.getCurrentUser();
        //获取用户权限 如果是admin 则是管理员 可以查看到全部
        Set<String> roles = currentUser.getRoles();
        Long creator = currentUser.getId();
        boolean roledesc= false;
        for (String role:roles) {
            if(role.equals(SecurityConstant.SUPER_ROLE)){
                roledesc=true;
            }
        }
        if(roledesc){

        }else{
            queryWrapper.eq("responsibility_user_id",creator);
        }
        List<ExecProject> execProjects = baseMapper.selectList(queryWrapper);
        return ApiResult.successWithData(execProjects);
    }

    @Override
    public ApiResult allweeklyreport(List ids) {
        LambdaQueryWrapper<ExecProject> queryWrapper = new LambdaQueryWrapper<>();
        SecurityUser currentUser = SecurityUtils.getCurrentUser();
        //获取用户权限 如果是admin 则是管理员 可以查看到全部
        Set<String> roles = currentUser.getRoles();
        Long creator = currentUser.getId();
        boolean roledesc= false;
        for (String role:roles) {
            if(role.equals(SecurityConstant.SUPER_ROLE)){
                roledesc=true;
            }
        }
        if(ids.size()>0){
            queryWrapper.in(ExecProject::getId,ids);
        }
        if(roledesc){

        }else{
            queryWrapper.eq(ExecProject::getResponsibilityUserId,creator);
        }
        List<ExecProject> execProjects = baseMapper.selectList(queryWrapper);
        List list = new ArrayList();
        execProjects.forEach(e->{
            QueryWrapper<WeeklyReport> Wrapper = new QueryWrapper<>();
            Long id = e.getId();
            String name = e.getName();
            Wrapper.eq("project_id",id);
            List<WeeklyReport> weeklyReports = weeklyReportMapper.selectList(Wrapper);
            if(weeklyReports.size()>0){
                HashMap<String,Object> weeklyhashMap = new HashMap();
                weeklyhashMap.put("oneWeekly",null);
                weeklyhashMap.put("oneNextplan",null);
                weeklyhashMap.put("twoWeekly",null);
                weeklyhashMap.put("twoNextplan",null);
                weeklyhashMap.put("threeWeekly",null);
                weeklyhashMap.put("threeExtplan",null);
                weeklyhashMap.put("fourWeekly",null);
                weeklyhashMap.put("fourExtplan",null);
                weeklyReports.forEach(week ->{
                    weeklyhashMap.put("id",id);
                    weeklyhashMap.put("projectName",name);
                    weeklyhashMap.put("weekNum",week.getWeeks());
                    Integer currentWeek = week.getCurrentWeek();
                    if(currentWeek==1){
                        weeklyhashMap.put("oneWeekly",week.getWeeklyReport());
                        weeklyhashMap.put("oneNextplan",week.getNextPlan());
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        if("".equals(week.getFillingDate())||null==week.getFillingDate()){

                        }else{
                            weeklyhashMap.put("oneFillingDate",df.format(week.getFillingDate()));
                        }
                    }
                    if(currentWeek==2){
                        weeklyhashMap.put("twoWeekly",week.getWeeklyReport());
                        weeklyhashMap.put("twoNextplan",week.getNextPlan());
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        if("".equals(week.getFillingDate())||null==week.getFillingDate()){

                        }else{
                            weeklyhashMap.put("twoFillingDate",df.format(week.getFillingDate()));
                        }
                    }
                    if(currentWeek==3){
                        weeklyhashMap.put("threeWeekly",week.getWeeklyReport());
                        weeklyhashMap.put("threeExtplan",week.getNextPlan());
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        if("".equals(week.getFillingDate())||null==week.getFillingDate()){

                        }else{
                            weeklyhashMap.put("threeFillingDate",df.format(week.getFillingDate()));
                        }
                    }
                    if(currentWeek==4){
                        weeklyhashMap.put("fourWeekly",week.getWeeklyReport());
                        weeklyhashMap.put("fourExtplan",week.getNextPlan());
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        if("".equals(week.getFillingDate())||null==week.getFillingDate()){

                        }else{
                            weeklyhashMap.put("fourFillingDate",df.format(week.getFillingDate()));
                        }
                    }
                    if(currentWeek==5) {
                        weeklyhashMap.put("fiveEweekly",week.getWeeklyReport());
                        weeklyhashMap.put("fiveEextplan",week.getNextPlan());
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        if("".equals(week.getFillingDate())||null==week.getFillingDate()){

                        }else{
                            weeklyhashMap.put("fiveFillingDate",df.format(week.getFillingDate()));
                        }
                    }
                    list.add(weeklyhashMap);
                });
            }
        });
        return ApiResult.successWithData(list);
    }
    /**
     * 修改新增接通、主从表通过项目编码进行关联
     * param ExecProjectDto
     * return ApiResult
     * describe 项目新建/编辑立项操作
     * @author 禾丰
     * @date 2021/12/31 10:03
     */
    @Override
    @Transactional
    public ApiResult add(ExecProjectDto execProjectDto) {
        try {
            //项目基本信息
            ExecProject execProject = execProjectDto.getExecProject();
            int select = select(execProject.getProjectNumber());
            if(select>0){
                return ApiResult.builder().code(500).msg("项目编码重复").build();
            }
            execProject.setSearchType("par");
            execProject.setApprovalStatus(0);//默认进入待审批状态 （经过审批后进行修改）
            baseMapper.insert(execProject);
            //判断、如果是待立项项目申请立项需要修改招投标项目状态为已立项
            if(execProject.getBidProjectId()!=null){
                changeBidStatus(execProject.getBidProjectId());
            }
            //则判断客户是否在客户表中已存在
            QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
            customerQueryWrapper.lambda().eq(Customer::getPhone,execProject.getCustomerPhone());
            Integer count = customerMapper.selectCount(customerQueryWrapper);
            //不存在则在客户表里插入客户信息（公司名称、客户姓名、客户电话）
            if(count==0){
                Long clueProjectId = null;
                if(execProject.getBidProjectId()!=null){
                    //根据招投标项目id查询线索id
                    BidProject bidProject = bidProjectMapper.selectById(execProject.getBidProjectId());
                    clueProjectId = bidProject.getRelatedProjectCuesId();
                }else if(execProject.getClueProjectId()!=null){
                    clueProjectId=execProject.getClueProjectId();
                }
                if(clueProjectId!=null){
                    //根据项目线索查询出公司信息
                    ClueProject clueProject = clueProjectMapper.selectById(clueProjectId);
                    CustomerOrganiza customerOrganiza = new CustomerOrganiza();
                    customerOrganiza.setCustomerName(execProject.getCustomerName());
                    customerOrganiza.setCustomerId(clueProject.getCustomerCompanyId());
                    //根据公司编码查找到公司名称
                    customerOrganiza.setPhonea(execProject.getCustomerPhone());
                    customerOrganiza.setPersonnelName(clueProject.getXsname());
                    customerOrganizaMapper.insert(customerOrganiza);
                }
            }
            //项目阶段信息
            List<ExecProjectStage> execProjectStageList = execProjectDto.getExecProjectStageList();
            if (null != execProjectStageList) {
                execProjectStageList.forEach(e -> {
                    List<AttachmentDto> attachments = e.getAttachments();
                    if(attachments != null && attachments.size() > 0){
                        String json = JSONArray.toJSONString(attachments);
                        e.setAchment(json);
                    }
                    //设置项目编码
                    e.setRelationId(execProject.getId());
                    e.setProjectNumber(execProject.getProjectNumber());
                    execProjectStageMapper.insert(e);
                    /**
                     * 保存附件项目相关的公共方法
                     *
                     * @param attachments 附件集合
                     * @param source      来源  根据 DirectoryTypeEnum
                     * @param relationId  业务id
                     * @param sourceId    如果一个表单有多个附件，用于标识附件属于表单的哪个附件
                     * @param  projectNumber 项目编号 全局唯一
                     */
                    if(attachments != null && attachments.size() > 0){
                        directoryService.saveProAttachment(attachments, DirectoryTypeEnum.PRO_PM_CREATE.getCode(),String.valueOf(e.getId()),"1",execProject.getProjectNumber());
                    }
                });
            }
            //项目合同列表(合同附件暂未处理，待后续确定处理了逻辑再添加)
            List<ExecProjectContract> execProjectContractList = execProjectDto.getExecProjectContractList();
            if (null != execProjectContractList) {
                execProjectContractList.forEach(e -> {
                    List<AttachmentDto> attachments = e.getAttachments();
                    if(attachments != null && attachments.size() > 0){
                        String json = JSONArray.toJSONString(attachments);
                        e.setAchment(json);
                    }
                    e.setRelationId(execProject.getId());
                    e.setProjectNumber(execProject.getProjectNumber());
                    execProjectContractMapper.insert(e);
                    /**
                     * 保存附件项目相关的公共方法
                     *
                     * @param attachments 附件集合
                     * @param source      来源  根据 DirectoryTypeEnum
                     * @param relationId  业务id
                     * @param sourceId    如果一个表单有多个附件，用于标识附件属于表单的哪个附件
                     * @param  projectNumber 项目编号 全局唯一
                     */
                    if(attachments != null && attachments.size() > 0){
                        directoryService.saveProAttachment(attachments, DirectoryTypeEnum.PRO_PM_CREATE.getCode(),String.valueOf(e.getId()),"1",execProject.getProjectNumber());
                    }
                });
            }
            //采购预算
            List<ExecProjectCost> execProjectCostList = execProjectDto.getExecProjectCostList();
            if (null != execProjectCostList) {
                execProjectCostList.forEach(e -> {
                    e.setRelationId(execProject.getId());
                    e.setProjectNumber(execProject.getProjectNumber());
                    execProjectCostMapper.insert(e);
                });
            }
            //添加参与人员
            List<ExecProjectContributor> execProjectContributorList = execProjectDto.getExecProjectContributorList();
            if (null != execProjectContributorList) {
                execProjectContributorList.forEach(e -> {
                    e.setRelationId(execProject.getId());
                    e.setProjectNumber(execProject.getProjectNumber());
                    execProjectContributorMapper.insert(e);
                });
            }

            //添加审批人
            //项目审批开始
            List<ApplyForApproval> execProjectCheckList = execProjectDto.getExecProjectCheckList();
            if (null != execProjectCheckList) {
                execProjectCheckList.forEach(e ->{
                    //业务表主键
                    e.setRelationId(execProject.getId());
                    //业务表编码
                    e.setRelationCode(execProject.getProjectNumber());
                    /**
                     * 关联审批分类 1、合同审批 2、协同审批 3、投标审批  4、立项审批  5、验收审批
                     * 6、成本变更审批  7、进度变更审批  8、研发立项审批  9、采购审批
                     */
                    e.setRelationType(4);
                });
                applyForApprovalService.addApproval(execProjectCheckList);
            }
            //项目审批结束
            //添加抄送人
            List<ApplyForApproval> execProjectNoticeList = execProjectDto.getExecProjectNoticeList();
            if (null != execProjectNoticeList) {
                execProjectNoticeList.forEach(e -> {
                    //业务表主键
                    e.setRelationId(execProject.getId());
                    //业务表编码
                    e.setRelationCode(execProject.getProjectNumber());
                    /**
                     * 关联审批分类 1、合同审批 2、协同审批 3、投标审批  4、立项审批  5、验收审批
                     * 6、成本变更审批  7、进度变更审批  8、研发立项审批  9、采购审批
                     */
                    e.setRelationType(4);
                });
                applyForApprovalService.addCarbonCopy(execProjectNoticeList);
            }
        } catch (Exception e) {
            log.error("[项目新建立项操作] error---{}", e.getMessage());
            e.printStackTrace();
            return ApiResult.fail();
        }
        return ApiResult.simpleSuccess();
    }

    @Override
    public ApiResult addplan(ExecProjectDto execProjectDto) {
        //项目基本信息
        ExecProject execProject = execProjectDto.getExecProject();
        //采购预算
        List<ExecProjectCost> execProjectCostList = execProjectDto.getExecProjectCostList();
        if (null != execProjectCostList) {
            execProjectCostList.forEach(e -> {
                e.setRelationId(execProject.getId());
                e.setProjectNumber(execProject.getProjectNumber());
                execProjectCostMapper.insert(e);
            });
        }
        //成本计划
        List<ExecProjectCostPlan> ExecProjectCostPlanList = execProjectDto.getExecProjectCostPlans();
        if (null != ExecProjectCostPlanList) {
            execProjectCostList.forEach(e -> {
                e.setRelationId(execProject.getId());
                e.setProjectNumber(execProject.getProjectNumber());
                execProjectCostPlanMapper.insert(e);
            });
        }
        return null;
    }

    /**
     * param execProject
     * return ApiResult
     * describe 新增子项目
     * @author liyansheng
     * @date 2022-1-11 17:25:11
     */
    @Override
    @Transactional
    public ApiResult addSub(ExecProject execProject) {
        List<AttachmentDto> attachments = execProject.getAttachments();
        if(attachments != null && attachments.size() > 0){
            String json = JSONArray.toJSONString(attachments);
            execProject.setAchment(json);
        }
        execProject.setApprovalStatus(1);//默认设置成审批通过
        execProject.setSearchType("sub");
        baseMapper.insert(execProject);
        /**
         * 保存附件项目相关的公共方法
         *
         * @param attachments 附件集合
         * @param source      来源  根据 DirectoryTypeEnum
         * @param relationId  业务id
         * @param sourceId    如果一个表单有多个附件，用于标识附件属于表单的哪个附件
         * @param  projectNumber 项目编号 全局唯一
         */
        if(attachments != null && attachments.size() > 0){
            directoryService.saveProAttachment(attachments, DirectoryTypeEnum.PRO_PM_CREATE.getCode(),String.valueOf(execProject.getId()),"1",execProject.getProjectNumber());
        }
        return ApiResult.simpleSuccess();
    }

    /**
     * 编辑立项项目（如果实体中存在id则按照修改进行操作、如果实体中id为空则执行插入操作）
     * @Author liyansheng
     * @param execProject
     * @return
     */
    @Override
    @Transactional
    public ApiResult updateSub(ExecProject execProject) {
        List<AttachmentDto> attachments = execProject.getAttachments();
        if(attachments != null && attachments.size() > 0){
            String json = JSONArray.toJSONString(attachments);
            execProject.setAchment(json);
        }
        UpdateWrapper<ExecProject> updateWrapper = new UpdateWrapper();
        updateWrapper.lambda()
                .eq(ExecProject::getId,execProject.getId())
                .set(ExecProject::getUpdateTime,execProject.getUpdateTime())
                .set(ExecProject::getName,execProject.getName())
                .set(ExecProject::getResponsibilityUserId,execProject.getResponsibilityUserId())
                .set(ExecProject::getResponsibilityUserName,execProject.getResponsibilityUserName())
                .set(ExecProject::getType,execProject.getType())
                .set(ExecProject::getPlanMoney,execProject.getPlanMoney())
                .set(ExecProject::getSubStages,execProject.getSubStages())
                .set(ExecProject::getSubContracts,execProject.getSubContracts())
                .set(ExecProject::getFileIds,execProject.getFileIds())
                .set(ExecProject::getStartDate,execProject.getStartDate())
                .set(ExecProject::getEndDate,execProject.getEndDate())
                .set(ExecProject::getAchment,execProject.getAchment())
                .set(ExecProject::getWeight,execProject.getWeight())
                ;
        baseMapper.update(null, updateWrapper);
        return ApiResult.simpleSuccess();
    }

    /**
     * param name项目名称
     * return  List<ExecProjectVo>
     * describe 项目立项管理列表
     * @author 禾丰
     * @date 2022/1/4
     */
    @Override
    public ApiResult list(ExecProjectPage pageDto) {
        //封装查询条件
        QueryWrapper<ExecProject> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotEmpty(pageDto.getParentProjectNumber())){
            queryWrapper.eq("parent_project_number",pageDto.getParentProjectNumber());
        }
        if(StringUtils.isNotEmpty(pageDto.getParentName())){
            queryWrapper.like("parent_name",pageDto.getParentName());
        }
        if(StringUtils.isNotEmpty(pageDto.getProjectNumber())){
            queryWrapper.like("project_number",pageDto.getProjectNumber());
        }
        if(StringUtils.isNotEmpty(pageDto.getType())){
            queryWrapper.eq("search_type","sub");
        }else{
            queryWrapper.eq("search_type","par");
        }
        if(StringUtils.isNotEmpty(pageDto.getName())){
            queryWrapper.like("name",pageDto.getName());
        }
        if(StringUtils.isNotEmpty(pageDto.getProjectNumber())){
            queryWrapper.like("project_number",pageDto.getProjectNumber());
        }
        if(!(null==pageDto.getResponsibilityUserId())){
            queryWrapper.eq("responsibility_user_id",pageDto.getResponsibilityUserId());
        }
        if(ManagerEnum.GENERAL.toString().equals(SecurityUtils.getCurrentUser().getManager())){
            Long id = SecurityUtils.getCurrentUser().getId();
            queryWrapper.lambda().eq(ExecProject::getResponsibilityUserId,id).or().eq(ExecProject::getCreator,id);
        }
        queryWrapper.orderByDesc("id");
        Page<ExecProject> page = new Page<>(pageDto.getPage(),pageDto.getSize());
        IPage<ExecProject> pages = baseMapper.selectPage(page,queryWrapper.orderByDesc("create_time"));
        //对查询结果进行封装
        if(pages.getTotal() != 0){
            pages.getRecords()
                .forEach(e-> {
                    int id = pages.getRecords().indexOf(e);
                    BigDecimal planMoney = e.getPlanMoney();
                    System.out.println(planMoney+"-------------------------------------");
                    if(planMoney==null||"".equals(planMoney)||"null".equals(planMoney)){
                        e.setPlanMoneyName("￥0");
                        BigDecimal bd = new BigDecimal("0");
                        e.setPlanMoney(bd);
                    }else{
                        e.setPlanMoneyName("￥"+e.getPlanMoney());
                    }
                    //项目风险100%及以上良好；80%-100%低风险；60%-80%中风险；60%及以下高风险
                    //前端要求传递编码 0-良好  1-低风险  2-中风险 3-高风险(需要计算)
                    e.setProjectRisk(id%4);
                    //项目进度(需要计算)
                    e.setProjectProgress("50%");
                    //项目成本(需要计算)
                    e.setProjectCost("￥100");
                    //项目经理赋值
                    SysUser sysUser = sysUserMapper.selectById(e.getResponsibilityUserId());
                    if(sysUser!=null){
                        e.setResponsibilityUserName(sysUser.getNickname());
                    }
                    if(e.getType()!=null){
                        e.setTypeName(ProjectType.getByCode(e.getType()));
                    }
                    //设置项目状态
                    e.setProjectStatus(dealProjectStatus(e));
                    //查询子项目
                    if("par".equals(e.getSearchType())){
                        //根据项目编码查询子项目
                        QueryWrapper<ExecProject> q = new QueryWrapper<>();
                        q.lambda().eq(ExecProject::getParentProjectNumber,e.getProjectNumber());
                        List<ExecProject> execProjects = baseMapper.selectList(q);
                        e.setChildren(execProjects);

                    }
                });
        }
        return ApiResult.successWithData(pages);
    }

    /**
     * 设置项目状态
     * @param e
     * @return
     */
    private Integer dealProjectStatus(ExecProject e) {
        //0-待立项  项目建立后审批通过前或审批驳回状态
        Integer status = 0;
        if(1!=e.getApprovalStatus()){
            return status;
        }else{
            //1-进行中 审批通过
            status = 1;
            //2-验收中 验收申请通过、合同未全部验收（查询验收表验收状态）
            QueryWrapper<ExecProjectExamine> queryWrapper = new QueryWrapper();
            queryWrapper.lambda().eq(ExecProjectExamine::getProjectNumber,e.getProjectNumber())
                    .eq(ExecProjectExamine::getApprovalStatus,1)
                    .isNull(ExecProjectExamine::getParentId);
            ExecProjectExamine execProjectExamine = execProjectExamineMapper.selectOne(queryWrapper);
            if(execProjectExamine!=null){
                status = 2;//验收中
                //3-质保中 判断是否有质保数据（如果有且状态在志保中的则在质保中，如果有或者没有则在验收中或结项）
                QueryWrapper<ExecProjectExamine> queryWrapper1 = new QueryWrapper();
                queryWrapper1.lambda().eq(ExecProjectExamine::getProjectNumber,e.getProjectNumber())
                        .isNotNull(ExecProjectExamine::getParentId);
                List<ExecProjectExamine> execProjectExamines = execProjectExamineMapper.selectList(queryWrapper1);
                if(execProjectExamines!=null&&execProjectExamines.size()>0){
                    for (ExecProjectExamine en:execProjectExamines) {
                        //判断验收阶段是否完成（完成后进入质保或结项）
                        if(en.getCheckStageId()==4){
                            status = 3;// 3-质保中  如果验收阶段到验收完成则进入质保阶段（判断是否有质保，如果有则是质保中，如果没有则是结项）
                            QueryWrapper<ProjectWarranty> queryWrapperProjectWarranty= new QueryWrapper();
                            queryWrapperProjectWarranty.lambda().eq(ProjectWarranty::getProjectNumber,e.getProjectNumber())
                                    .in(ProjectWarranty::getWarrantyStatus,new ArrayList<Integer>(){ {this.add(0);this.add(2);}});
                            List<ProjectWarranty> projectWarranties = projectWarrantyMapper.selectList(queryWrapperProjectWarranty);
                            if (projectWarranties==null||projectWarranties.size()==0){
                                status = 4; //4-结项
                            }
                            break;
                        }
                    }
                }
            }
        }
        return status;
    }

    /**
     * param id 项目立项id
     * return  ExecProjectDetailVo项目立项详情
     * describe 项目立项详情
     * @author 禾丰
     * @date 2022/1/4
     * 立项系列的其他表可能需要加中间表,逻辑就会改动
     */
    @Override
    public ApiResult detail(Long id) {
        //封装详情信息
        ExecProjectDto execProjectDto = new ExecProjectDto();
        //根据id主键查询立项信息
        ExecProject execProject = baseMapper.selectById(id);
        SysUser sysUser = sysUserMapper.selectById(execProject.getResponsibilityUserId());
        if(sysUser!=null){
            execProject.setResponsibilityUserName(sysUser.getNickname());
        }
        ClueProject clueProject = clueProjectMapper.selectById(execProject.getClueProjectId());
        if(clueProject!=null){
            execProject.setClueProjectName(clueProject.getXsname());
        }
        execProjectDto.setExecProject(execProject);
        //项目阶段信息列表
        QueryWrapper<ExecProjectStage> execProjectStageQueryWrapper = new QueryWrapper<>();
        execProjectStageQueryWrapper.lambda().eq(ExecProjectStage::getRelationId, execProject.getId());
        List<ExecProjectStage> execProjectStages = execProjectStageMapper.selectList(execProjectStageQueryWrapper);
        execProjectStages.forEach(e ->{
            String achment = e.getAchment();
            if(StringUtils.isNotEmpty(achment)){
                e.setAchment("");
                e.setAttachment(JSONObject.parseArray(achment, Attachment.class));
            }
        });
        execProjectDto.setExecProjectStageList(execProjectStages);
        //合同信息列表 todo
        QueryWrapper<ExecProjectContract> execProjectContractWrapper = new QueryWrapper<>();
        execProjectContractWrapper.lambda().eq(ExecProjectContract::getRelationId, execProject.getId());
        List<ExecProjectContract> execProjectContracts = execProjectContractMapper.selectList(execProjectContractWrapper);
        execProjectContracts.forEach(e ->{
            String achment = e.getAchment();
            if(StringUtils.isNotEmpty(achment)){
                e.setAchment("");
                e.setAttachment(JSONObject.parseArray(achment, Attachment.class));
            }
        });
        execProjectDto.setExecProjectContractList(execProjectContracts);
        //采购列表
        QueryWrapper<ExecProjectCost> execProjectCostWrapper = new QueryWrapper<>();
        execProjectCostWrapper.lambda().eq(ExecProjectCost::getRelationId, execProject.getId());
        List<ExecProjectCost> execProjectCosts = execProjectCostMapper.selectList(execProjectCostWrapper);
        execProjectCosts.forEach(e->{
            CustomerSupplier customerSupplier = customerSupplierMapper.selectById(e.getSupplierId());
            if(customerSupplier!=null){
                e.setSupplierName(customerSupplier.getSupplierName());
            }
        });
        execProjectDto.setExecProjectCostList(execProjectCosts);
        //参与人员列表
        QueryWrapper<ExecProjectContributor> execProjectContributorWrapper = new QueryWrapper<>();
        execProjectContributorWrapper.lambda().eq(ExecProjectContributor::getRelationId, execProject.getId());
        List<ExecProjectContributor> execProjectContributors = execProjectContributorMapper.selectList(execProjectContributorWrapper);
        execProjectContributors.forEach(e->{
            SysUser sysUser1 = sysUserMapper.selectById(e.getUserId());
            if(sysUser1!=null){
                e.setUserName(sysUser1.getNickname());
            }
        });
        execProjectDto.setExecProjectContributorList(execProjectContributors);
        //审批人列表
        //关联审批分类 1、合同审批 2、协同审批 3、投标审批  4、立项审批  5、验收审批
        //6、成本变更审批  7、进度变更审批  8、研发立项审批  9、采购审批
        List<ApplyForApproval> applyForApprovals = applyForApprovalService.selectApprovalUser(id,4);
        execProjectDto.setExecProjectCheckList(applyForApprovals);
        //抄送人列表
        //关联审批分类 1、合同审批 2、协同审批 3、投标审批  4、立项审批  5、验收审批
        //6、成本变更审批  7、进度变更审批  8、研发立项审批  9、采购审批
        List<ApplyForApproval> applyForApprovals1 = applyForApprovalService.selectCopyUser(id,4);
        execProjectDto.setExecProjectNoticeList(applyForApprovals1);
        return ApiResult.successWithData(execProjectDto);
    }

    /**
     * param id
     * return  int
     * describe 删除立项信息
     * @author liyansheng
     * @date 2022-1-10 13:27:38
     */
    @Override
    @Transactional
    public int del(Long id) {
        //删除立项表数据
        baseMapper.deleteById(id);
        //删除项目阶段表数据
        QueryWrapper<ExecProjectStage> execProjectStageQueryWrapper = new QueryWrapper<>();
        execProjectStageQueryWrapper.lambda().eq(ExecProjectStage::getRelationId, id);
        execProjectStageMapper.delete(execProjectStageQueryWrapper);
        //删除合同数据
        QueryWrapper<ExecProjectContract> execProjectContractWrapper = new QueryWrapper<>();
        execProjectContractWrapper.lambda().eq(ExecProjectContract::getRelationId, id);
        execProjectContractMapper.delete(execProjectContractWrapper);
        //删除采购数据
        QueryWrapper<ExecProjectCost> execProjectCostWrapper = new QueryWrapper<>();
        execProjectCostWrapper.lambda().eq(ExecProjectCost::getRelationId, id);
        execProjectCostMapper.delete(execProjectCostWrapper);
        //删除参与人数据
        QueryWrapper<ExecProjectContributor> execProjectContributorQueryWrapper = new QueryWrapper<>();
        execProjectContributorQueryWrapper.lambda().eq(ExecProjectContributor::getRelationId, id);
        execProjectContributorMapper.delete(execProjectContributorQueryWrapper);
        //删除审批人、抄送人
        applyForApprovalService.delApprovalCopyUser(id);
        return 0;
    }
    /**
     * 根据id删除立项数据（项目删除的同时删除子项目）
     * type: stage-阶段 contract-合同 cost-预算 contributor-参与人员 check-审批人 notice-抄送人
     * @param type,id
     * @author liyansheng
     * @return
     */
    @Override
    @Transactional
    public int delUpdate(String type, Long id) {
        if(type.equals("stage")){
            execProjectStageMapper.deleteById(id);
        }else if(type.equals("contract")){
            execProjectContractMapper.deleteById(id);
        }else if(type.equals("cost")){
            execProjectCostMapper.deleteById(id);
        }else if(type.equals("contributor")){
            execProjectContributorMapper.deleteById(id);
        }else if(type.equals("check")){
            execProjectCheckMapper.deleteById(id);
        }else if(type.equals("notice")){
            execProjectNoticeMapper.deleteById(id);
        }
        return 0;
    }

    /**
     * param id
     * return  int
     * describe 删除子项目
     * @author liyansheng
     * @date 2022-1-10 13:27:38
     */
    @Override
    @Transactional
    public int delSub(String projectNumber) {
        //删除立项表数据
        QueryWrapper<ExecProject> execProjectQueryWrapper = new QueryWrapper<>();
        execProjectQueryWrapper.lambda().eq(ExecProject::getProjectNumber, projectNumber);
        baseMapper.delete(execProjectQueryWrapper);
        return 0;
    }

    /**
     * 判断项目编码是否存在
     * param projectNumber 项目编码
     * return  int
     * @author liyansheng
     * @date 2022-1-10 13:27:38
     */
    @Override
    public int select(String projectNumber) {
        //如果为空直接返回
        if(!StringUtils.isNotEmpty(projectNumber)){
            return 0;
        }
        //根据编码查询总数，统计编码是否存在，不存在返回0，存在返回1
        QueryWrapper<ExecProject> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ExecProject::getProjectNumber,projectNumber)
                .ne(ExecProject::getApprovalStatus,2);//查询非审批驳回的
        return baseMapper.selectCount(wrapper);
    }

    /**
     * 根据项目编码查询项目
     * @param projectNumber
     * @return
     */
    @Override
    public ExecProject selectProject(String projectNumber) {
        //如果为空直接返回
        if(!StringUtils.isNotEmpty(projectNumber)){
            return null;
        }
        //根据编码查询总数，统计编码是否存在，不存在返回0，存在返回1
        QueryWrapper<ExecProject> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ExecProject::getProjectNumber,projectNumber);
        return baseMapper.selectOne(wrapper);
    }

    /**
     * param id 项目立项id
     * return  ExecProject
     * describe 子项目详情
     * @author 禾丰
     * @date 2022/1/4
     */
    @Override
    public ExecProject subDetail(Long id) {
        ExecProject execProject = null;
        try {
            execProject = baseMapper.selectById(id);
            String achment = execProject.getAchment();
            if(StringUtils.isNotEmpty(achment)){
                execProject.setAchment("");
                execProject.setAttachment(JSONObject.parseArray(achment, Attachment.class));
            }
        } catch (Exception e) {
            log.error("[子项目详情页] error---{}", e.getMessage());
            e.printStackTrace();
        }
        return execProject;
    }

    /**
     * 根据父项目编码查询阶段
     * @param projectNumber
     * @Author liyansheng
     * @return
     */
    @Override
    public List<ExecProjectStage> selectStage(String projectNumber) {
        QueryWrapper<ExecProjectStage> execQueryWrapper = new QueryWrapper<>();
        Long relationId = getKey(projectNumber);
        execQueryWrapper.lambda().eq(ExecProjectStage::getRelationId, relationId);
        List<ExecProjectStage> execProjectStages = execProjectStageMapper.selectList(execQueryWrapper);
        //对结果集进行遍历
        execProjectStages.forEach(e-> {
            //通过枚举给字段赋值
            e.setStageName(ProjectStages.getByCode(e.getStageStatus()));
            if(e.getAchment() != null){
                e.setAttachments(JSONObject.parseArray(e.getAchment(), AttachmentDto.class));
            }
        });
        return execProjectStages;
    }

    /**
     * 子项目参与合同
     * @param projectNumber
     * @Author liyansheng
     * @return
     */
    @Override
    public List<ExecProjectContract> selectContract(String projectNumber) {
        QueryWrapper<ExecProjectContract> execQueryWrapper = new QueryWrapper<>();
        Long relationId = getKey(projectNumber);
        execQueryWrapper.lambda().eq(ExecProjectContract::getRelationId, relationId);
        List<ExecProjectContract> execProjectContract = execProjectContractMapper.selectList(execQueryWrapper);
        return execProjectContract;
    }

    /**
     * 根据项目编码查询项目主键
     * @param projectNumber
     * @return
     */
    public Long getKey(String projectNumber){
        QueryWrapper<ExecProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ExecProject::getProjectNumber, projectNumber)
                .ne(ExecProject::getApprovalStatus, 2);//不是驳回的
        ExecProject execProject = baseMapper.selectOne(queryWrapper);
        return execProject.getId();
    }

    /**
     * 修改合同数据(回款金额、回款计划)，同时修改状态为已验收
     * @param execProjectContracts
     * @Author liyansheng
     * @return
     */
    @Override
    @Transactional
    public int updateContract(List<ExecProjectContract> execProjectContracts) {
        execProjectContracts.forEach(e->{
            UpdateWrapper<ExecProjectContract> updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id",e.getId());
            updateWrapper.set("accept_status",1);
            updateWrapper.set("returned_money",e.getReturnedMoney());
            updateWrapper.set("returned_plan",e.getReturnedPlan());
            updateWrapper.set("update_time", LocalDateTime.now());
            execProjectContractMapper.update(null, updateWrapper);
        });
        return 0;
    }

    /**
     * 查询所有父项目(审批通过的)
     * @return
     */
    @Override
    public List<ExecProject> selectProjects() {
        // 获取当前用户
        Long creator = SecurityUtils.getCurrentUser().getId();
        //查询角色 如果是admin 则查看全部
        Set<String> roles = SecurityUtils.getCurrentUser().getRoles();
        QueryWrapper<ExecProject> execQueryWrapper = new QueryWrapper<>();
        for (String role:roles) {
            if(role.equals(SecurityConstant.SUPER_ROLE)){
                execQueryWrapper.lambda().eq(ExecProject::getSearchType,"par")
                        .eq(ExecProject::getApprovalStatus,1);
            }else{
                if(ManagerEnum.GENERAL.toString().equals(SecurityUtils.getCurrentUser().getManager())){
                    //查询他所负责的所有系项
                    execQueryWrapper.lambda().eq(ExecProject::getSearchType,"par")
                            .eq(ExecProject::getApprovalStatus,1)
                            .eq(ExecProject::getResponsibilityUserId,creator).or().eq(ExecProject::getCreator,creator);
                }else{
                    execQueryWrapper.lambda().eq(ExecProject::getSearchType,"par")
                            .eq(ExecProject::getApprovalStatus,1);
                }
            }
        }
        List<ExecProject> execProject = baseMapper.selectList(execQueryWrapper);
        execProject.forEach(e->{
            e.setParentProjectNumber(e.getProjectNumber());
        });
        return execProject;
    }

    /**
     * 查询项目经理
     * @return
     */
    @Override
    public List<SysUser> manager() {
        List<SysUser>  sysUsers= sysUserService.listAll();
        sysUsers.forEach(e->{
            e.setUsername(e.getNickname());
        });
        return sysUsers;
    }

    /**
     * 用户接口
     * @return
     */
    @Override
    public List<HashMap<String,Object>> users() {
        List<HashMap<String,Object>> users = new ArrayList<HashMap<String,Object>>();
        List<SysUser>  sysUsers= sysUserService.listAll();
        sysUsers.forEach(e->{
            HashMap<String,Object> hashMap = new HashMap<String,Object>();
            hashMap.put("userId",e.getId());
            hashMap.put("userName",e.getNickname());
            users.add(hashMap);
        });
        return users;
    }

    /**
     * 查询部门
     * @return
     */
    @Override
    public List<SysDept> dept() {
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysDept::getDel, false);
        List<SysDept>  sysDept= sysDeptMapper.selectList(wrapper);
        return sysDept;
    }

    /**
     * 查询所有售前项目
     * @return
     */
    @Override
    public List<ClueProject> clueProject() {
        QueryWrapper<ClueProject> wrapper = new QueryWrapper<>();
        wrapper.eq("delldust","0");
        List<ClueProject> clueProjects = clueProjectMapper.selectList(wrapper);
        return clueProjects;
    }

    /**
     * @param id
     * return  ApiResult
     * @describe 更新阶段状态
     * @author liyansheng
     * @date 2022-1-12 19:06:25
     */
    @Override
    @Transactional
    public ApiResult changeStage(Long id) {
        UpdateWrapper<ExecProjectStage> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id",id);
        updateWrapper.set("accept_status",1);
        updateWrapper.set("update_time", LocalDateTime.now());
        int update = execProjectStageMapper.update(null, updateWrapper);
        return ApiResult.successWithData(update);
    }

    @Override
    public ApiResult changeBidStatus(Long id) {
        UpdateWrapper<BidProject> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id",id);
        updateWrapper.set("to_project",1); //改为已立项
        updateWrapper.set("update_time", LocalDateTime.now());
        int update = bidProjectMapper.update(null, updateWrapper);
        return ApiResult.successWithData(update);
    }

    /**
     * 根据公司编码查询审批通过的父项目
     * @param id
     * @return
     */
    @Override
    public int getListBySql(Long id) {
        List<ExecProject> listBySql = baseMapper.getListBySql(id);
        if(listBySql==null){
            return 0;
        }
        return listBySql.size();
    }

    /**
     * 子项目编号生成
     * @param execProject
     * @return
     */
    @Override
    public String SubSerial(ExecProject execProject) {

        QueryWrapper<ExecProject> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_project_number",execProject.getParentProjectNumber());
        wrapper.orderByDesc("create_time");
        wrapper.last("LIMIT 1");
        ExecProject selectOne = baseMapper.selectOne(wrapper);
        if (selectOne ==null ){
            //创建一个子项目
            String sub1 = execProject.getParentProjectNumber() +"-001";
            return  sub1;
            }else {
//            QueryWrapper<ExecProject> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("parent_project_number", execProject.getParentProjectNumber());
//            queryWrapper.orderByDesc("create_time");
//            queryWrapper.last("LIMIT 1");
            ExecProject project = baseMapper.selectOne(wrapper);

                String projectNumber = project.getProjectNumber();
                Integer number = Integer.parseInt(projectNumber.substring(projectNumber.lastIndexOf("-") + 1));
                number += 1;
                String lastNum = "";
                for (int i = 0; i < 3 - number.toString().length(); i++) {
                    lastNum += "0";
                }
                String s = String.valueOf(number);
                String sub = execProject.getParentProjectNumber() + "-" + lastNum + s;
                return sub;
        }

    }


    /**
     * 查询所有审批通过的父项目
     * @return
     */
    @Override
    public List<ExecProject> getPars() {
        QueryWrapper<ExecProject> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ExecProject::getApprovalStatus,1)
                .eq(ExecProject::getSearchType,"par");
        List<ExecProject> execProjects = baseMapper.selectList(wrapper);
        return execProjects;
    }
}
